import fs from 'fs'
import { PrismaClient as PgClient } from '../../../prisma/generated/uctoo'
require('dotenv').config()
const {  DATABASE_URL } = process.env
const db = new PgClient({
  log: ['query', 'info', 'warn', 'error'],
  datasourceUrl: DATABASE_URL,
});

async function main() {
  const args = process.argv.slice(2); // 去掉数组中的前两个元素
  let dbName = args[0] ? args[0] : 'uctoo';
  const needLangs = args[1] ? args[1] : 'false' // 增加追加语言包
  // let path = process.cwd()
  let path = `${process.env.HARMONYOSAPP_DIRECTORY}/commondb/src/main`
 
  // 从db_info取出所有表
  try {
    // 查询是否存在数据库
    const result = await db.db_info.findMany({
      where: { is_table_hidden: 'NO', table_catalog: dbName },
      distinct: ['table_name'],
      orderBy: { table_name: "asc" }
    })
    console.log("result:", result.length)
    if (result.length === 0) {
      // 不存在，获取数据库信息失败
      console.log(`select db_info fail.`)
    } else {
      for (const row of result) {
        let tableName = row.table_name
        const SKIP_TABLES = ['_prisma_migrations', 'group_has_permission'];
        if (SKIP_TABLES.includes(tableName)) { //跳过人工维护的表不进行自动代码生成
          continue;
        }
        // 首字母小写
        let tableNameLower = convertToCamelCase(tableName)
        // 首字母大写
        const tableNameUpper = `${tableNameLower.charAt(0).toLocaleUpperCase()}${tableNameLower.slice(1)}`
        //  取出表结构fields
        const fields = await db.db_info.findMany({
          where: { table_name: tableName, is_column_hidden: 'NO' },
          orderBy: { ordinal_position: 'asc' }
        })
        console.log(tableName, ",fields:", fields.length)

        if (fields.length > 0) { 
          const modelTplFile = `${path}/ets/rdbDatabase/uctoo/models/entity.ets.tpl`
          const modelTargetPath = `${path}/ets/rdbDatabase/${dbName}/models`
          const storeIndexPath = `${path}/ets/rdbDatabase/index.ets`
          createModel(fields, tableName, tableNameUpper, tableNameLower, modelTplFile, modelTargetPath, storeIndexPath, dbName)
          const viewmodelTplFile = `${path}/ets/viewmodel/uctoo/entity/EntityViewModel.ets.tpl`
          const viewmodelTargetPath = `${path}/ets/viewmodel/${dbName}/${tableName}`
          const viewmodelStoreIndexPath = `${path}/ets/viewmodel/index.ets`
          createViewModel(fields, tableName, tableNameUpper, tableNameLower, viewmodelTplFile, viewmodelTargetPath, viewmodelStoreIndexPath, dbName)
          const viewTitleViewTplFile = `${path}/ets/view/uctoo/entity/EntityTitleView.ets.tpl`
          const viewTitleViewTargetPath = `${path}/ets/view/${dbName}/${tableName}`
          const viewTitleViewIndexPath = `${path}/ets/view/index.ets`
          createTitleView(fields, tableName, tableNameUpper, tableNameLower, viewTitleViewTplFile, viewTitleViewTargetPath, viewTitleViewIndexPath, dbName)
          const viewListViewTplFile = `${path}/ets/view/uctoo/entity/EntityListView.ets.tpl`
          const viewListViewTargetPath = `${path}/ets/view/${dbName}/${tableName}`
          const viewTListViewIndexPath = `${path}/ets/view/index.ets`
          createListView(fields, tableName, tableNameUpper, tableNameLower, viewListViewTplFile, viewListViewTargetPath, viewTListViewIndexPath, dbName)
          const viewItemViewTplFile = `${path}/ets/view/uctoo/entity/EntityItemView.ets.tpl`
          const viewItemViewTargetPath = `${path}/ets/view/${dbName}/${tableName}`
          const viewTItemViewIndexPath = `${path}/ets/view/index.ets`
          createItemView(fields, tableName, tableNameUpper, tableNameLower, viewItemViewTplFile, viewItemViewTargetPath, viewTItemViewIndexPath, dbName)
          const viewCloudListViewTplFile = `${path}/ets/view/uctoo/entity/CloudEntityListView.ets.tpl`
          const viewCloudListViewTargetPath = `${path}/ets/view/${dbName}/${tableName}`
          const viewCloudListViewIndexPath = `${path}/ets/view/index.ets`
          createCloudListView(fields, tableName, tableNameUpper, tableNameLower, viewCloudListViewTplFile, viewCloudListViewTargetPath, viewCloudListViewIndexPath, dbName)
          const pagesCloudListPageTplFile = `${path}/ets/pages/uctoo/entity/CloudEntityListPage.ets.tpl`
          const pagesCloudListPageTargetPath = `${path}/ets/pages/${dbName}/${tableName}`
          const pagesCloudListPageIndexPath = `${path}/ets/pages/index.ets`
          createCloudListPage(fields, tableName, tableNameUpper, tableNameLower, pagesCloudListPageTplFile, pagesCloudListPageTargetPath, pagesCloudListPageIndexPath, dbName)
          const pagesListPageTplFile = `${path}/ets/pages/uctoo/entity/EntityListPage.ets.tpl`
          const pagesListPageTargetPath = `${path}/ets/pages/${dbName}/${tableName}`
          const pagesListPageIndexPath = `${path}/ets/pages/index.ets`
          createListPage(fields, tableName, tableNameUpper, tableNameLower, pagesListPageTplFile, pagesListPageTargetPath, pagesListPageIndexPath, dbName)

          if (needLangs == "true") {
            const langsTargetPath = `${path}/resources`
          //  appendLangs(fields, tableName, langsTargetPath)
          }
        }
      }
    }
  } catch (ex) {
    console.error(ex)
  }

}

function convertToCamelCase(str) {
  return str.toLowerCase().replace(/_(.)/g, function (match, group1) {
    return group1.toUpperCase();
  });
}

function typeConversion(type) {
  switch (type) {
    case "integer": return "number";
    case "Int": return "number";
    case "double precision": return "number";
    case "character varying": return "string";
    case "String": return "string";
    case "timestamp with time zone": return "Date";
    case "DateTime": return "Date";
    default: return "string"
  }
}
function typeDefaultValue(type) {
  // return "\"\""
  switch (type) {
    case "integer": return 0;
    case "Int": return 0;
    case "double precision": return 0;
    case "character varying": return "''";
    case "String": return "''";
    case "timestamp with time zone": return "new Date()";
    case "DateTime": return "new Date()";
    default: return "''"
  }
}
function typeRdbModelType(type) {
  switch (type) {
    case "uuid": return "TEXT";
    case "integer": return "INTEGER";
    case "Int": return "INTEGER";
    case "double precision": return "REAL";
    case "text": return "TEXT";
    case "character varying": return "TEXT";
    case "String": return "TEXT";
    case "timestamp with time zone": return "TEXT";
    case "DateTime": return "TEXT";
    default: return "TEXT"
  }
}
function typeRdbArkTSType(type) {
  switch (type) {
    case "uuid": return "string";
    case "integer": return "number";
    case "Int": return "number";
    case "double precision": return "number";
    case "text": return "string";
    case "character varying": return "string";
    case "String": return "string";
    case "timestamp with time zone": return "string";
    case "DateTime": return "string";
    default: return "string"
  }
}
function typeDefaultModelValue(type) {
  switch (type) {
    case "uuid": return "''";
    case "integer": return 0;
    case "Int": return 0;
    case "double precision": return 0;
    case "character varying": return "''";
    case "String": return "''";
    case "timestamp with time zone": return "''";
    case "DateTime": return "''";
    default: return "''"
  }
}
function resetDefaultValue(type) {
  // return "\"\""
  switch (type) {
    case "integer": return 0;
    case "Int": return 0;
    case "double precision": return 0;
    case "character varying": return "''";
    case "String": return "''";
    case "timestamp with time zone": return null;
    case "DateTime": return null;
    default: return "''"
  }
}

// 生成types.ts文件
function createTypes(fields, tableNameUpper, tableNameLower, targetPath) {
  let context = `export interface ${tableNameUpper} {\r\n`
  context += `[property: string]: any;\r\n`
  for (const field of fields) {
    let str = '?';
    if (field.is_nullable === "NO") {
      str = '';
    }
    context += `${field.column_name}${str}:${typeConversion(field.data_type)};\r\n`
  }
  context += `}\r\n`
  context += `export interface ${tableNameUpper}Response {
  [property: string]: any;
  currentPage: number;
  ${tableNameLower}s: ${tableNameUpper}[];
  total: number;
}`

  // 判断是否有目录，没有要创建
  if (!fs.existsSync(targetPath)) {
    try {
      fs.mkdirSync(targetPath, { recursive: true });
    } catch (err) {
      console.error(err);
    }
  }
  try {
    if (context) {
      fs.writeFileSync(`${targetPath}/types.ts`, context)
      console.log(`writeFile ${targetPath}/types.ts success!`)
    } else {
      console.log(`writeFile ${targetPath}/types.ts error! no context`)
    }
  } catch (err) {
    console.error('处理文件出错', err);
  }
}
// 生成models.ts文件
async function createModel(fields, tableName, tableNameUpper, tableNameLower, tplFile, targetPath, indexPath, dbName) {
  const targetFile = `${targetPath}/${tableName}.ets`;
  
  // 判断是否有目录，没有要创建
  if (!fs.existsSync(targetPath)) {
    try {
      fs.mkdirSync(targetPath, { recursive: true });
    } catch (err) {
      console.error(err);
    }
  }
  
  try {
    // 目标文件保留区内容提取
    const preservedRegions = [];
    if (fs.existsSync(targetFile)) {
      const targetContent = fs.readFileSync(targetFile, 'utf-8');
      targetContent.replace(
        /\/\/#region Human-Code Preservation([\s\S]*?)\/\/#endregion Human-Code Preservation/g,
        (match, content) => {
          preservedRegions.push(content.trim());
          return match;
        }
      );
    }

    // 原有模板处理逻辑
    let context = fs.readFileSync(tplFile, 'utf-8');
    if (context) {
      // 模板预处理（添加占位符）
      let placeholderIndex = 0;
      context = context.replace(
        /\/\/#region Human-Code Preservation[\s\S]*?\/\/#endregion Human-Code Preservation/g,
        () => {
          const placeholder = `//#PRESERVE_${placeholderIndex++}#//`;
          return `//#region Human-Code Preservation\n${placeholder}\n//#endregion Human-Code Preservation`;
        }
      );

      // 处理rdb模型的字段生成
      let modelFields = ``;
      let modelToString = ``;
      let modelEditParams = ``;
      let modelSelectKey = ``;
      let modelFromJson = ``;
      let modelRemoveEmpty = ``;
      let modelRemoveNull = ``;
      let modelFormated = ``;

      for (const field of fields) {
        modelToString += `      ${field.column_name}: this.${field.column_name},\r\n`;
        if (field.column_name === 'id') { // id字段已经处理过了modelFields
          modelFields += `@Columns({name: '${field.column_name}', type: ColumnType.${typeRdbModelType(field.data_type)}, isPrimaryKey: true, autoincrement: false})\r\n  ${field.column_name}: ${typeRdbArkTSType(field.data_type)} = ${typeDefaultModelValue(field.data_type)}\r\n`
          modelEditParams += `${field.column_name}: ${typeRdbArkTSType(field.data_type)}\r\n`;
          modelSelectKey += `{ value: '${field.column_name}' },\r\n`;
          modelFromJson += `${tableName}Obj.${field.column_name} = jsonData.${field.column_name} ?? ${typeDefaultModelValue(field.data_type)};\r\n`;
          modelRemoveEmpty += `if (obj.${field.column_name} !== null && obj.${field.column_name} !== undefined && obj.${field.column_name} !== ${typeDefaultModelValue(field.data_type)}) result.${field.column_name} = obj.${field.column_name};\r\n`;
          modelRemoveNull += `if (obj.${field.column_name} !== null && obj.${field.column_name} !== undefined) result.${field.column_name} = obj.${field.column_name};\r\n`;
          modelFormated += `${field.column_name}?: ${typeRdbArkTSType(field.data_type)} | null,\r\n`;
        }else if (field.column_name === 'creator' || field.column_name === 'deleted_at') { //前后端模型约束不同可为空 creator和deleted_at字段默认值为null
          modelFields += `  @Columns({name: '${field.column_name}', type: ColumnType.${typeRdbModelType(field.data_type)} })\r\n  ${field.column_name}: ${typeRdbArkTSType(field.data_type)} | null = null\r\n`;
          
          modelEditParams += `  ${field.column_name}?: ${typeRdbArkTSType(field.data_type)}\r\n`;
          modelSelectKey += `      { value: '${field.column_name}' },\r\n`;
          modelFromJson += `      ${tableName}Obj.${field.column_name} = jsonData.${field.column_name} ?? null\r\n`;
          modelRemoveEmpty += `if (obj.${field.column_name} !== null && obj.${field.column_name} !== undefined && obj.${field.column_name} !== ${typeDefaultModelValue(field.data_type)}) result.${field.column_name} = obj.${field.column_name};\r\n`;
          modelRemoveNull += `if (obj.${field.column_name} !== null && obj.${field.column_name} !== undefined) result.${field.column_name} = obj.${field.column_name};\r\n`;
          modelFormated += `${field.column_name}?: ${typeRdbArkTSType(field.data_type)} | null,\r\n`;
        } else {
          modelFields += `  @Columns({name: '${field.column_name}', type: ColumnType.${typeRdbModelType(field.data_type)} })\r\n  ${field.column_name}: ${typeRdbArkTSType(field.data_type)} ${field.is_nullable === "NO" ? '' : '| null'} = ${typeDefaultModelValue(field.data_type)}\r\n`;
          
          modelEditParams += `  ${field.column_name}?: ${typeRdbArkTSType(field.data_type)}\r\n`;
          modelSelectKey += `      { value: '${field.column_name}' },\r\n`;
          modelFromJson += `      ${tableName}Obj.${field.column_name} = jsonData.${field.column_name} ?? ${typeDefaultModelValue(field.data_type)};\r\n`;
          modelRemoveEmpty += `if (obj.${field.column_name} !== null && obj.${field.column_name} !== undefined && obj.${field.column_name} !== ${typeDefaultModelValue(field.data_type)}) result.${field.column_name} = obj.${field.column_name};\r\n`;
          modelRemoveNull += `if (obj.${field.column_name} !== null && obj.${field.column_name} !== undefined) result.${field.column_name} = obj.${field.column_name};\r\n`;
          modelFormated += `${field.column_name}?: ${typeRdbArkTSType(field.data_type)} | null,\r\n`;
        }
      }
      modelToString += ``;
      modelEditParams += ``;

      context = context
        .replace(/_TableName_/g, tableNameUpper)
        .replace(/_tableName_/g, tableNameLower)
        .replace(/_table_name_/g, tableName)
        .replace("REPLACE_MODELFIELDS", modelFields)
        .replace("REPLACE_MODELTOSTRING", modelToString)
        .replace("REPLACE_MODELEDITPARAMS", modelEditParams)
        .replace("REPLACE_SELECTKEY", modelSelectKey)
        .replace("REPLACE_MODELFROMJSON", modelFromJson)
        .replace("REPLACE_REMOVEEMPTY", modelRemoveEmpty)
        .replace("REPLACE_REMOVENULL", modelRemoveNull)
        .replace("REPLACE_MODELFORMATED", modelFormated);

      // 恢复保留内容
      placeholderIndex = 0;
      context = context.replace(
        /\/\/#region Human-Code Preservation\n\/\/#PRESERVE_(\d+)#\/\/\n\/\/#endregion Human-Code Preservation/g,
        (match, index) => {
          const content = preservedRegions[Number(index)] || '';
          return `//#region Human-Code Preservation\n${content}\n//#endregion Human-Code Preservation`;
        }
      );  
    
      fs.writeFileSync(targetFile, context);
      
      //index.ts文件中添加导出语句
      const newPath = `./${dbName}/models/${tableName}`;
      appendUniqueExport(indexPath, newPath);
      console.log(`writeFile ${targetFile} success!`);
    }
  } catch (err) {
    console.error('处理文件出错', err);
  }
}

// 生成viewmodel 文件
async function createViewModel(fields, tableName, tableNameUpper, tableNameLower, tplFile, targetPath, indexPath, dbName) {
  const targetFile = `${targetPath}/${tableNameUpper}ViewModel.ets`;
  
  // 判断是否有目录，没有要创建
  if (!fs.existsSync(targetPath)) {
    try {
      fs.mkdirSync(targetPath, { recursive: true });
    } catch (err) {
      console.error(err);
    }
  }
  
  try {
    // 目标文件保留区内容提取
    const preservedRegions = [];
    if (fs.existsSync(targetFile)) {
      const targetContent = fs.readFileSync(targetFile, 'utf-8');
      targetContent.replace(
        /\/\/#region Human-Code Preservation([\s\S]*?)\/\/#endregion Human-Code Preservation/g,
        (match, content) => {
          preservedRegions.push(content.trim());
          return match;
        }
      );
    }

    // 原有模板处理逻辑
    let context = fs.readFileSync(tplFile, 'utf-8');
    if (context) {
      // 模板预处理（添加占位符）
      let placeholderIndex = 0;
      context = context.replace(
        /\/\/#region Human-Code Preservation[\s\S]*?\/\/#endregion Human-Code Preservation/g,
        () => {
          const placeholder = `//#PRESERVE_${placeholderIndex++}#//`;
          return `//#region Human-Code Preservation\n${placeholder}\n//#endregion Human-Code Preservation`;
        }
      );

      // 处理rdb viewmodel的字段生成
      let modelFields = ``;
      let modelKeys = ``;
      let modelEditParams = ``;
      let modelGetValue = ``;
      let modelFromEntity = ``;
      let modelToEntity = ``;

      for (const field of fields) {
        modelKeys += `      '${field.column_name}',\r\n`;
        modelGetValue += `      case '${field.column_name}': return instance.${field.column_name}?.toString() ?? '';\r\n`
        modelFromEntity += `      ${field.column_name}: ${tableName}Obj.${field.column_name} ?? undefined,\r\n`;
        modelToEntity += `    ${tableName}Obj.${field.column_name} = this.${field.column_name};\r\n`;
        if (field.column_name === 'id') { // id字段已经处理过了modelFields
          modelFields += `  @Trace public ${field.column_name}: ${typeRdbArkTSType(field.data_type)} ${field.is_nullable === "NO" ? '' : '| null'} = ${typeDefaultModelValue(field.data_type)};\r\n`;
          modelEditParams += `      this.${field.column_name} = data.${field.column_name}  ?? ${typeDefaultModelValue(field.data_type)};\r\n`;
        }else if (field.column_name === 'creator' || field.column_name === 'deleted_at') { //前后端模型约束不同可为空 creator和deleted_at字段默认值为null
          modelFields += `  @Trace public ${field.column_name}: ${typeRdbArkTSType(field.data_type)} ${field.is_nullable === "NO" ? '' : '| null'} = ${typeDefaultModelValue(field.data_type)};\r\n`;
          modelEditParams += `      this.${field.column_name} = data.${field.column_name}  ?? ${typeDefaultModelValue(field.data_type)};\r\n`;  
        } else {
          modelFields += `  @Trace public ${field.column_name}: ${typeRdbArkTSType(field.data_type)} ${field.is_nullable === "NO" ? '' : '| null'} = ${typeDefaultModelValue(field.data_type)};\r\n`;
          modelEditParams += `      this.${field.column_name} = data.${field.column_name}  ?? ${typeDefaultModelValue(field.data_type)};\r\n`;
        }
      }
      modelKeys += ``;
      modelEditParams += ``;

      context = context
        .replace(/_TableName_/g, tableNameUpper)
        .replace(/_tableName_/g, tableNameLower)
        .replace(/_table_name_/g, tableName)
        .replace("REPLACE_VIEWMODEL", modelFields)
        .replace("REPLACE_VIEWMODELKEYS", modelKeys)
        .replace("REPLACE_VIEWMODELCONSTRUCTOR", modelEditParams)
        .replace("REPLACE_VIEWMODELGETVALUE", modelGetValue)
        .replace("REPLACE_VIEWMODELFROMENTITY", modelFromEntity)
        .replace("REPLACE_VIEWMODELTOENTITY", modelToEntity);

      // 恢复保留内容
      placeholderIndex = 0;
      context = context.replace(
        /\/\/#region Human-Code Preservation\n\/\/#PRESERVE_(\d+)#\/\/\n\/\/#endregion Human-Code Preservation/g,
        (match, index) => {
          const content = preservedRegions[Number(index)] || '';
          return `//#region Human-Code Preservation\n${content}\n//#endregion Human-Code Preservation`;
        }
      );  
    
      fs.writeFileSync(targetFile, context);
      
      //index.ts文件中添加导出语句
      const newPath = `./${dbName}/${tableName}/${tableNameUpper}ViewModel`;
      appendUniqueExport(indexPath, newPath);
      console.log(`writeFile ${targetFile} success!`);
    }
  } catch (err) {
    console.error('处理文件出错', err);
  }
}
// 生成view/TitleView 文件
async function createTitleView(fields, tableName, tableNameUpper, tableNameLower, tplFile, targetPath, indexPath, dbName) {
  const targetFile = `${targetPath}/${tableNameUpper}TitleView.ets`;
  
  // 判断是否有目录，没有要创建
  if (!fs.existsSync(targetPath)) {
    try {
      fs.mkdirSync(targetPath, { recursive: true });
    } catch (err) {
      console.error(err);
    }
  }
  
  try {
    // 目标文件保留区内容提取
    const preservedRegions = [];
    if (fs.existsSync(targetFile)) {
      const targetContent = fs.readFileSync(targetFile, 'utf-8');
      targetContent.replace(
        /\/\/#region Human-Code Preservation([\s\S]*?)\/\/#endregion Human-Code Preservation/g,
        (match, content) => {
          preservedRegions.push(content.trim());
          return match;
        }
      );
    }

    // 原有模板处理逻辑
    let context = fs.readFileSync(tplFile, 'utf-8');
    if (context) {
      // 模板预处理（添加占位符）
      let placeholderIndex = 0;
      context = context.replace(
        /\/\/#region Human-Code Preservation[\s\S]*?\/\/#endregion Human-Code Preservation/g,
        () => {
          const placeholder = `//#PRESERVE_${placeholderIndex++}#//`;
          return `//#region Human-Code Preservation\n${placeholder}\n//#endregion Human-Code Preservation`;
        }
      );

      // 处理rdb viewmodel的字段生成

      context = context
        .replace(/_TableName_/g, tableNameUpper)
        .replace(/_tableName_/g, tableNameLower)
        .replace(/_table_name_/g, tableName)

      // 恢复保留内容
      placeholderIndex = 0;
      context = context.replace(
        /\/\/#region Human-Code Preservation\n\/\/#PRESERVE_(\d+)#\/\/\n\/\/#endregion Human-Code Preservation/g,
        (match, index) => {
          const content = preservedRegions[Number(index)] || '';
          return `//#region Human-Code Preservation\n${content}\n//#endregion Human-Code Preservation`;
        }
      );  
    
      fs.writeFileSync(targetFile, context);
      
      //index.ts文件中添加导出语句
      const newPath = `./${dbName}/${tableName}/${tableNameUpper}TitleView`;
      appendUniqueExport(indexPath, newPath);
      console.log(`writeFile ${targetFile} success!`);
    }
  } catch (err) {
    console.error('处理文件出错', err);
  }
}
// 生成view/ListView 文件
async function createListView(fields, tableName, tableNameUpper, tableNameLower, tplFile, targetPath, indexPath, dbName) {
  const targetFile = `${targetPath}/${tableNameUpper}ListView.ets`;
  
  // 判断是否有目录，没有要创建
  if (!fs.existsSync(targetPath)) {
    try {
      fs.mkdirSync(targetPath, { recursive: true });
    } catch (err) {
      console.error(err);
    }
  }
  
  try {
    // 目标文件保留区内容提取
    const preservedRegions = [];
    if (fs.existsSync(targetFile)) {
      const targetContent = fs.readFileSync(targetFile, 'utf-8');
      targetContent.replace(
        /\/\/#region Human-Code Preservation([\s\S]*?)\/\/#endregion Human-Code Preservation/g,
        (match, content) => {
          preservedRegions.push(content.trim());
          return match;
        }
      );
    }

    // 原有模板处理逻辑
    let context = fs.readFileSync(tplFile, 'utf-8');
    if (context) {
      // 模板预处理（添加占位符）
      let placeholderIndex = 0;
      context = context.replace(
        /\/\/#region Human-Code Preservation[\s\S]*?\/\/#endregion Human-Code Preservation/g,
        () => {
          const placeholder = `//#PRESERVE_${placeholderIndex++}#//`;
          return `//#region Human-Code Preservation\n${placeholder}\n//#endregion Human-Code Preservation`;
        }
      );

      // 处理rdb viewmodel的字段生成

      context = context
        .replace(/_TableName_/g, tableNameUpper)
        .replace(/_tableName_/g, tableNameLower)
        .replace(/_table_name_/g, tableName)

      // 恢复保留内容
      placeholderIndex = 0;
      context = context.replace(
        /\/\/#region Human-Code Preservation\n\/\/#PRESERVE_(\d+)#\/\/\n\/\/#endregion Human-Code Preservation/g,
        (match, index) => {
          const content = preservedRegions[Number(index)] || '';
          return `//#region Human-Code Preservation\n${content}\n//#endregion Human-Code Preservation`;
        }
      );  
    
      fs.writeFileSync(targetFile, context);
      
      //index.ts文件中添加导出语句
      const newPath = `./${dbName}/${tableName}/${tableNameUpper}ListView`;
      appendUniqueExport(indexPath, newPath);
      console.log(`writeFile ${targetFile} success!`);
    }
  } catch (err) {
    console.error('处理文件出错', err);
  }
}
// 生成view/ItemView 文件
async function createItemView(fields, tableName, tableNameUpper, tableNameLower, tplFile, targetPath, indexPath, dbName) {
  const targetFile = `${targetPath}/${tableNameUpper}ItemView.ets`;
  
  // 判断是否有目录，没有要创建
  if (!fs.existsSync(targetPath)) {
    try {
      fs.mkdirSync(targetPath, { recursive: true });
    } catch (err) {
      console.error(err);
    }
  }
  
  try {
    // 目标文件保留区内容提取
    const preservedRegions = [];
    if (fs.existsSync(targetFile)) {
      const targetContent = fs.readFileSync(targetFile, 'utf-8');
      targetContent.replace(
        /\/\/#region Human-Code Preservation([\s\S]*?)\/\/#endregion Human-Code Preservation/g,
        (match, content) => {
          preservedRegions.push(content.trim());
          return match;
        }
      );
    }

    // 原有模板处理逻辑
    let context = fs.readFileSync(tplFile, 'utf-8');
    if (context) {
      // 模板预处理（添加占位符）
      let placeholderIndex = 0;
      context = context.replace(
        /\/\/#region Human-Code Preservation[\s\S]*?\/\/#endregion Human-Code Preservation/g,
        () => {
          const placeholder = `//#PRESERVE_${placeholderIndex++}#//`;
          return `//#region Human-Code Preservation\n${placeholder}\n//#endregion Human-Code Preservation`;
        }
      );

      // 处理rdb viewmodel的字段生成

      context = context
        .replace(/_TableName_/g, tableNameUpper)
        .replace(/_tableName_/g, tableNameLower)
        .replace(/_table_name_/g, tableName)

      // 恢复保留内容
      placeholderIndex = 0;
      context = context.replace(
        /\/\/#region Human-Code Preservation\n\/\/#PRESERVE_(\d+)#\/\/\n\/\/#endregion Human-Code Preservation/g,
        (match, index) => {
          const content = preservedRegions[Number(index)] || '';
          return `//#region Human-Code Preservation\n${content}\n//#endregion Human-Code Preservation`;
        }
      );  
    
      fs.writeFileSync(targetFile, context);
      
      //index.ts文件中添加导出语句
      const newPath = `./${dbName}/${tableName}/${tableNameUpper}ItemView`;
      appendUniqueExport(indexPath, newPath);
      console.log(`writeFile ${targetFile} success!`);
    }
  } catch (err) {
    console.error('处理文件出错', err);
  }
}
// 生成view/CloudListView 文件
async function createCloudListView(fields, tableName, tableNameUpper, tableNameLower, tplFile, targetPath, indexPath, dbName) {
  const targetFile = `${targetPath}/Cloud${tableNameUpper}ListView.ets`;
  
  // 判断是否有目录，没有要创建
  if (!fs.existsSync(targetPath)) {
    try {
      fs.mkdirSync(targetPath, { recursive: true });
    } catch (err) {
      console.error(err);
    }
  }
  
  try {
    // 目标文件保留区内容提取
    const preservedRegions = [];
    if (fs.existsSync(targetFile)) {
      const targetContent = fs.readFileSync(targetFile, 'utf-8');
      targetContent.replace(
        /\/\/#region Human-Code Preservation([\s\S]*?)\/\/#endregion Human-Code Preservation/g,
        (match, content) => {
          preservedRegions.push(content.trim());
          return match;
        }
      );
    }

    // 原有模板处理逻辑
    let context = fs.readFileSync(tplFile, 'utf-8');
    if (context) {
      // 模板预处理（添加占位符）
      let placeholderIndex = 0;
      context = context.replace(
        /\/\/#region Human-Code Preservation[\s\S]*?\/\/#endregion Human-Code Preservation/g,
        () => {
          const placeholder = `//#PRESERVE_${placeholderIndex++}#//`;
          return `//#region Human-Code Preservation\n${placeholder}\n//#endregion Human-Code Preservation`;
        }
      );

      // 处理rdb viewmodel的字段生成

      context = context
        .replace(/_TableName_/g, tableNameUpper)
        .replace(/_tableName_/g, tableNameLower)
        .replace(/_table_name_/g, tableName)

      // 恢复保留内容
      placeholderIndex = 0;
      context = context.replace(
        /\/\/#region Human-Code Preservation\n\/\/#PRESERVE_(\d+)#\/\/\n\/\/#endregion Human-Code Preservation/g,
        (match, index) => {
          const content = preservedRegions[Number(index)] || '';
          return `//#region Human-Code Preservation\n${content}\n//#endregion Human-Code Preservation`;
        }
      );  
    
      fs.writeFileSync(targetFile, context);
      
      //index.ts文件中添加导出语句
      const newPath = `./${dbName}/${tableName}/Cloud${tableNameUpper}ListView`;
      appendUniqueExport(indexPath, newPath);
      console.log(`writeFile ${targetFile} success!`);
    }
  } catch (err) {
    console.error('处理文件出错', err);
  }
}
// 生成pages/CloudListPage 文件
async function createCloudListPage(fields, tableName, tableNameUpper, tableNameLower, tplFile, targetPath, indexPath, dbName) {
  const targetFile = `${targetPath}/Cloud${tableNameUpper}ListPage.ets`;
  
  // 判断是否有目录，没有要创建
  if (!fs.existsSync(targetPath)) {
    try {
      fs.mkdirSync(targetPath, { recursive: true });
    } catch (err) {
      console.error(err);
    }
  }
  
  try {
    // 目标文件保留区内容提取
    const preservedRegions = [];
    if (fs.existsSync(targetFile)) {
      const targetContent = fs.readFileSync(targetFile, 'utf-8');
      targetContent.replace(
        /\/\/#region Human-Code Preservation([\s\S]*?)\/\/#endregion Human-Code Preservation/g,
        (match, content) => {
          preservedRegions.push(content.trim());
          return match;
        }
      );
    }

    // 原有模板处理逻辑
    let context = fs.readFileSync(tplFile, 'utf-8');
    if (context) {
      // 模板预处理（添加占位符）
      let placeholderIndex = 0;
      context = context.replace(
        /\/\/#region Human-Code Preservation[\s\S]*?\/\/#endregion Human-Code Preservation/g,
        () => {
          const placeholder = `//#PRESERVE_${placeholderIndex++}#//`;
          return `//#region Human-Code Preservation\n${placeholder}\n//#endregion Human-Code Preservation`;
        }
      );

      // 处理rdb viewmodel的字段生成

      context = context
        .replace(/_TableName_/g, tableNameUpper)
        .replace(/_tableName_/g, tableNameLower)
        .replace(/_table_name_/g, tableName)

      // 恢复保留内容
      placeholderIndex = 0;
      context = context.replace(
        /\/\/#region Human-Code Preservation\n\/\/#PRESERVE_(\d+)#\/\/\n\/\/#endregion Human-Code Preservation/g,
        (match, index) => {
          const content = preservedRegions[Number(index)] || '';
          return `//#region Human-Code Preservation\n${content}\n//#endregion Human-Code Preservation`;
        }
      );  
    
      fs.writeFileSync(targetFile, context);
      
      //index.ts文件中添加导出语句
      const newPath = `./${dbName}/${tableName}/Cloud${tableNameUpper}ListPage`;
      appendUniqueExport(indexPath, newPath);
      console.log(`writeFile ${targetFile} success!`);
    }
  } catch (err) {
    console.error('处理文件出错', err);
  }
}

// 生成pages/ListPage 文件
async function createListPage(fields, tableName, tableNameUpper, tableNameLower, tplFile, targetPath, indexPath, dbName) {
  const targetFile = `${targetPath}/${tableNameUpper}ListPage.ets`;
  
  // 判断是否有目录，没有要创建
  if (!fs.existsSync(targetPath)) {
    try {
      fs.mkdirSync(targetPath, { recursive: true });
    } catch (err) {
      console.error(err);
    }
  }
  
  try {
    // 目标文件保留区内容提取
    const preservedRegions = [];
    if (fs.existsSync(targetFile)) {
      const targetContent = fs.readFileSync(targetFile, 'utf-8');
      targetContent.replace(
        /\/\/#region Human-Code Preservation([\s\S]*?)\/\/#endregion Human-Code Preservation/g,
        (match, content) => {
          preservedRegions.push(content.trim());
          return match;
        }
      );
    }

    // 原有模板处理逻辑
    let context = fs.readFileSync(tplFile, 'utf-8');
    if (context) {
      // 模板预处理（添加占位符）
      let placeholderIndex = 0;
      context = context.replace(
        /\/\/#region Human-Code Preservation[\s\S]*?\/\/#endregion Human-Code Preservation/g,
        () => {
          const placeholder = `//#PRESERVE_${placeholderIndex++}#//`;
          return `//#region Human-Code Preservation\n${placeholder}\n//#endregion Human-Code Preservation`;
        }
      );

      // 处理rdb viewmodel的字段生成

      context = context
        .replace(/_TableName_/g, tableNameUpper)
        .replace(/_tableName_/g, tableNameLower)
        .replace(/_table_name_/g, tableName)

      // 恢复保留内容
      placeholderIndex = 0;
      context = context.replace(
        /\/\/#region Human-Code Preservation\n\/\/#PRESERVE_(\d+)#\/\/\n\/\/#endregion Human-Code Preservation/g,
        (match, index) => {
          const content = preservedRegions[Number(index)] || '';
          return `//#region Human-Code Preservation\n${content}\n//#endregion Human-Code Preservation`;
        }
      );  
    
      fs.writeFileSync(targetFile, context);
      
      //index.ts文件中添加导出语句
      const newPath = `./${dbName}/${tableName}/${tableNameUpper}ListPage`;
      appendUniqueExport(indexPath, newPath);
      console.log(`writeFile ${targetFile} success!`);
    }
  } catch (err) {
    console.error('处理文件出错', err);
  }
}

// 生成en-US.json、zh-CN.json文件
function appendLangs(fields, tableName, targetPath) {
  let enColumns = `"${tableName}":{\r\n`
  let cnColumns = `"${tableName}":{\r\n`
  for (let index = 0; index < fields.length; index++) {
    const field = fields[index];
    enColumns += `      "${field.column_name}": "${field.column_name}"`
    if (field.column_name === 'id') {
      cnColumns += `      "${field.column_name}": "id"`
    } else {
      const columnArr = field.column_comment ? field.column_comment.split('。') : []
      cnColumns += `      "${field.column_name}": "${columnArr.length ? columnArr[0] :
        (field.column_comment ? field.column_comment : field.column_name)}"`
    }
    if (index < fields.length - 1) {
      cnColumns += `,`;
      enColumns += `,`
    }
    cnColumns += `\r\n`
    enColumns += `\r\n`
  }
  for (const field of fields) {

  }
  enColumns += `    },\r\n   "AUTO_APPEND": "AUTO_APPEND_CODE"`
  cnColumns += `    },\r\n   "AUTO_APPEND": "AUTO_APPEND_CODE"`
  const enTargetFile = `${targetPath}/en-US.json`
  const cnTargetFile = `${targetPath}/zh-CN.json`
  // 判断是否有目录，没有要创建
  if (!fs.existsSync(targetPath)) {
    try {
      fs.mkdirSync(targetPath, { recursive: true });
    } catch (err) {
      console.error(err);
    }
  }
  try {
    enColumns = enColumns.replace(" ", "")
    const enData = fs.readFileSync(enTargetFile, 'utf-8')
    let enContext = enData
    if (enContext) {
      enContext = enContext.replace("\"AUTO_APPEND\": \"AUTO_APPEND_CODE\"", enColumns)
      fs.writeFileSync(enTargetFile, enContext)
      console.log(`writeFile ${enTargetFile} success!`)
    } else {
      console.log(`writeFile ${enTargetFile} error! no context`)
    }

    cnColumns = cnColumns.replace(" ", "")
    const cnData = fs.readFileSync(cnTargetFile, 'utf-8')
    let cnContext = cnData
    if (cnContext) {
      cnContext = cnContext.replace("\"AUTO_APPEND\": \"AUTO_APPEND_CODE\"", cnColumns)
      fs.writeFileSync(cnTargetFile, cnContext)
      console.log(`writeFile ${cnTargetFile} success!`)
    } else {
      console.log(`writeFile ${cnTargetFile} error! no context`)
    }
  } catch (err) {
    console.error('处理文件出错', err);
  }
}
/**
 * 向指定文件追加新的导出语句，并确保内容唯一
 * @param filePath 目标文件路径（如 index.ts）
 * @param newExportPath 要添加的新导出路径（如 './uctoo/models/uctoo_user'）
 */
function appendUniqueExport(filePath: string, newExportPath: string) {
  try {
    // 读取文件内容
    const content = fs.readFileSync(filePath, 'utf-8');
    const lines = content.split(/\r?\n/); // 兼容不同系统的换行符

    // 提取所有已存在的导出路径
    const exportPathRegex = /export \* from ['"](.*?)['"]/;
    const existingPaths = new Set<string>();
    
    for (const line of lines) {
      const match = line.match(exportPathRegex);
      if (match) existingPaths.add(match[1]);
    }

    // 判断路径是否存在并追加新行
    if (!existingPaths.has(newExportPath)) {
      const newLine = `export * from '${newExportPath}';`;
      lines.push(newLine);
      fs.writeFileSync(filePath, lines.join('\n'));
      console.log(`✅ 成功添加: ${newExportPath}`);
    } else {
      console.log(`⏩ 跳过重复: ${newExportPath}`);
    }
  } catch (error) {
    console.error('❌ 文件处理错误:', error);
  }
}
main()